2 we can use 13 bits to record which category is used,
3 one category is used is represented by setting a bit as follows,
5 for (int combi = 0, add = 1 << c; combi < ncombinations; ++combi) {
7 Here, combi represents the bit combination, and add is the new added category.
9 Secondly, we can use DP to find the best categorization
10 for each upper score (upper score refers to the sum score of the first
12 We need to record each of the 64 ([0, 63]) upper score conditions, and
13 if a new higher score with the same upper score could be achieved by
14 a new categorization, we could adjust the old categorization
15 for this new one as follows,
17 int newscore = score + dp[combi][u];
18 int newupper = upper + u < nupper ? upper + u : nupper - 1;
19 if (newscore > dp[combi|add][newupper]) {
20 dp[combi|add][newupper] = newscore;
21 previous[combi|add][newupper].combi = combi;
22 previous[combi|add][newupper].upper = u;
25 Here, previous is used to restore the categorization.
27 At last, we check for the best score within the upper scores
28 of full categorization, and give a bonus for the upper score of 63 as folllows,
30 int combi = ncombinations - 1;
31 int upper = nupper - 1;
33 score = dp[combi][upper] + bonus;
34 for (int u = 0; u < nupper; ++u) {
35 if (score < dp[combi][u]) {
43 Sebastian Arcila Valenzuela
44 sebastianarcila@gmail.com
76 #define D(x) cerr<<__LINE__<<" "#x" "<<x<<endl
77 #define D_v(x) for(int i=0;i<x.size();cerr<<x[i++]<<" ")
79 #define ALL(x) x.begin(),x.end()
85 const int n_c
= 13, n_r
= 13,n_d
= 5,combinations
= 8192,nupper
= 64;
87 int pop_count
[combinations
], dp
[combinations
][nupper
], scores
[n_r
][n_c
], categorization
[n_c
];
89 rec previous
[combinations
][nupper
];
91 int eval(const int &category
,const int dices
[])
93 int c
= category
+ 1,score
= 0;
102 for (int i
= 0; i
< n_d
; ++i
)
107 for (int i
= 0; i
< n_d
; ++i
)
111 if (dices
[0] == dices
[2] || dices
[1] == dices
[3] ||
112 dices
[2] == dices
[4])
113 for (int i
= 0; i
< n_d
; ++i
)
117 if (dices
[0] == dices
[3] || dices
[1] == dices
[4])
118 for (int i
= 0; i
< n_d
; ++i
)
122 if (dices
[0] == dices
[4])
126 if (dices
[0] == dices
[1]-1 && dices
[1] == dices
[2]-1 &&
127 dices
[2] == dices
[3]-1 || dices
[1] == dices
[2]-1 &&
128 dices
[2] == dices
[3]-1 && dices
[3] == dices
[4]-1)
132 if (dices
[0] == dices
[1]-1 && dices
[1] == dices
[2]-1 &&
133 dices
[2] == dices
[3]-1 && dices
[3] == dices
[4]-1)
137 if (dices
[0] == dices
[1] && dices
[2] == dices
[4] ||
138 dices
[0] == dices
[2] && dices
[3] == dices
[4])
147 void do_it(int& bonus
, int& score
)
150 for (int i
= 0; i
< combinations
; ++i
)
151 for (int j
= 0; j
< nupper
; ++j
)
156 for (int r
= 0; r
< n_r
; ++r
)
157 for (int c
= 0; c
< n_c
; ++c
)
159 int score
= scores
[r
][c
];
160 int upper
= c
< 6 ? score
: 0;
161 for (int combi
= 0, add
= 1 << c
; combi
< combinations
; ++combi
)
163 if (pop_count
[combi
] != r
|| combi
& add
) continue;
164 for (int u
= 0; u
< nupper
; ++u
)
166 int newscore
= score
+ dp
[combi
][u
];
167 int newupper
= upper
+ u
< nupper
? upper
+ u
: nupper
- 1;
168 if (newscore
> dp
[combi
|add
][newupper
])
170 dp
[combi
|add
][newupper
] = newscore
;
171 previous
[combi
|add
][newupper
].combi
= combi
;
172 previous
[combi
|add
][newupper
].upper
= u
;
178 int combi
= combinations
- 1;
179 int upper
= nupper
- 1;
181 score
= dp
[combi
][upper
] + bonus
;
182 for (int u
= 0; u
< nupper
; ++u
)
183 if (score
< dp
[combi
][u
])
186 score
= dp
[combi
][u
];
192 rec pre
= previous
[combi
][upper
];
194 for (int add
= combi
^ pre
.combi
; add
>>= 1; ++c
);
195 categorization
[c
] = dp
[combi
][upper
] - dp
[pre
.combi
][pre
.upper
];
204 /* Calcula todas las categorias de cada combinacion*/
205 for (int i
= 0; i
< combinations
; ++i
)
206 pop_count
[i
] = __builtin_popcount(i
);
209 int d
= 0, r
= 0, g
= 0;
210 while (scanf("%d",&dices
[d
++ % n_d
]) == 1)
214 sort(dices
, dices
+ n_d
);
215 for (int c
= 0; c
< n_c
; ++c
)
216 scores
[r
% n_r
][c
] = eval(c
,dices
);
226 for (int c
= 0; c
< n_c
; ++c
)
227 printf("%d ",categorization
[c
]);
229 printf("%d %d\n",bonus
,score
);